package controllers

import (
	"errors"
	"github.com/gin-gonic/gin"
	"golang.org/x/crypto/bcrypt"
	"gorm.io/gorm"
	"partyus_app/config"
	"partyus_app/global"
	"partyus_app/models"
	"partyus_app/response"
	"partyus_app/utils"
	"strconv"
)

// CreateUser 创建用户
func CreateUser(ctx *gin.Context) {
	var req struct {
		Username   string `json:"username" binding:"required"`
		Password   string `json:"password"` // 不要求必填
		Avatar     string `json:"avatar"`
		Email      string `json:"email" binding:"required"`
		Phone      string `json:"phone"`
		Department int    `json:"department"`
	}

	if err := ctx.ShouldBindJSON(&req); err != nil {
		response.CommonResp(ctx, 1, "参数错误", nil)
		return
	}

	if req.Avatar == "" {
		req.Avatar = config.DEFAULT_AVATAR
	}

	if req.Password == "" {
		req.Password = "123456" // 设置默认密码
	}

	// 检查邮箱是否已存在
	var existingUser models.User
	if err := global.Db.Where("email = ?", req.Email).First(&existingUser).Error; err == nil {
		response.CommonResp(ctx, 1, "该邮箱已被注册", nil)
		return
	} else if !errors.Is(err, gorm.ErrRecordNotFound) {
		response.CommonResp(ctx, 1, "创建用户时，数据库查询失败", nil)
		return
	}

	// 加密密码
	hashedPassword, err := bcrypt.GenerateFromPassword([]byte(req.Password), bcrypt.DefaultCost)
	if err != nil {
		response.CommonResp(ctx, 1, "密码加密失败", nil)
		return
	}

	user := models.User{
		Username:   req.Username,
		Password:   string(hashedPassword),
		Avatar:     req.Avatar,
		Email:      req.Email,
		Phone:      req.Phone,
		Department: req.Department,
	}

	// 创建用户
	if err := global.Db.Create(&user).Error; err != nil {
		response.CommonResp(ctx, 1, "用户创建失败", nil)
		return
	}

	response.CommonResp(ctx, 0, "用户创建成功", gin.H{"user": response.ToResponseUser(user)})
}

// DeleteUser 删除用户
func DeleteUser(ctx *gin.Context) {
	var req struct {
		ID int `json:"id" binding:"required"`
	}
	if err := ctx.ShouldBindJSON(&req); err != nil {
		response.CommonResp(ctx, 1, "参数错误", nil)
		return
	}

	if err := global.Db.Delete(&models.User{}, req.ID).Error; err != nil {
		response.CommonResp(ctx, 1, "用户删除失败", nil)
		return
	}
	response.CommonResp(ctx, 0, "用户删除成功", nil)
}

// GetUser 获取用户
func GetUser(ctx *gin.Context) {
	userIDStr := ctx.Query("id")
	userID, err := strconv.Atoi(userIDStr)
	if err != nil {
		response.CommonResp(ctx, 1, "参数错误", nil)
		return
	}

	var user models.User
	if err := global.Db.First(&user, userID).Error; err != nil {
		response.CommonResp(ctx, 1, "用户不存在", nil)
		return
	}
	respUser := response.ToResponseUser(user)
	response.CommonResp(ctx, 0, "获取用户成功", gin.H{"user": respUser})
}

// UpdateUser 更新用户
func UpdateUser(ctx *gin.Context) {
	var req struct {
		ID         int     `json:"id" binding:"required"`
		Username   *string `json:"username"`
		Password   *string `json:"password"`
		Avatar     *string `json:"avatar"`
		Email      *string `json:"email"`
		Phone      *string `json:"phone"`
		Department *int    `json:"department"`
	}

	if err := ctx.ShouldBindJSON(&req); err != nil {
		response.CommonResp(ctx, 1, "参数错误_u", nil)
		return
	}

	// 获取当前用户的角色和 ID
	userID, exists1 := ctx.Get("userID")
	role, exists2 := ctx.Get("role")

	if !exists1 || !exists2 {
		response.CommonResp(ctx, 1, "用户未登录或未授权", nil)
		return
	}

	currentUserID := userID.(int)
	currentRole := role.(int)
	// 权限检查
	//if currentRole != 0 && currentRole != 1 {
	//	response.CommonResp(ctx, 1, "权限不足", nil)
	//	return
	//}
	if currentRole != 0 && req.ID != currentUserID {
		response.CommonResp(ctx, 1, "权限不足，普通用户只能修改自己的信息", nil)
		return
	}
	// 限制 role=1 的用户不能提升自己的 role 字段
	if currentRole != 0 && req.Department != nil && *req.Department != currentRole {
		response.CommonResp(ctx, 1, "权限不足，无法改变自己的等级", nil)
		return
	}

	var user models.User
	if err := global.Db.Where("id = ? AND deleted_at IS NULL", req.ID).First(&user).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			response.CommonResp(ctx, 1, "用户不存在或已删除", nil)
		} else {
			response.CommonResp(ctx, 1, "查询失败", nil)
		}
		return
	}

	// 动态生成更新字段
	updates := make(map[string]interface{})

	if req.Username != nil {
		updates["username"] = *req.Username
	}
	if req.Avatar != nil {
		updates["avatar"] = *req.Avatar
	}
	if req.Email != nil {
		updates["email"] = *req.Email
	}
	if req.Phone != nil {
		updates["phone"] = *req.Phone
	}
	if req.Department != nil {
		updates["department"] = *req.Department
	}
	if req.Password != nil && *req.Password != "" {
		hashedPassword, err := bcrypt.GenerateFromPassword([]byte(*req.Password), bcrypt.DefaultCost)
		if err != nil {
			response.CommonResp(ctx, 1, "密码加密失败", nil)
			return
		}
		updates["password"] = string(hashedPassword)
	}

	if len(updates) == 0 {
		response.CommonResp(ctx, 1, "没有需要更新的字段", nil)
		return
	}

	if err := global.Db.Model(&user).Updates(updates).Error; err != nil {
		response.CommonResp(ctx, 1, "用户更新失败", nil)
		return
	}

	response.CommonResp(ctx, 0, "用户更新成功", gin.H{"user": response.ToResponseUser(user)})
}

func GetUserByEmail(ctx *gin.Context) {
	// 获取请求参数中的邮箱
	var req struct {
		Email string `json:"email" binding:"required"`
	}
	// 绑定请求体参数
	if err := ctx.ShouldBindJSON(&req); err != nil {
		response.CommonResp(ctx, 1, "参数错误", nil)
		return
	}

	// 查询数据库中是否存在该邮箱的用户
	var user models.User
	if err := global.Db.Where("email = ? AND deleted_at IS NULL", req.Email).First(&user).Error; err != nil {
		if err.Error() == "record not found" {
			// 如果没有找到用户
			response.CommonResp(ctx, 1, "用户不存在", nil)
		} else {
			// 如果查询发生其他错误
			response.CommonResp(ctx, 1, "查询失败", nil)
		}
		return
	}
	respUser := response.ToResponseUser(user)

	// 如果用户存在，返回用户信息
	response.CommonResp(ctx, 0, "查询成功", gin.H{"user": respUser})
}

func GetUserList(ctx *gin.Context) {
	// 1. 解析请求参数
	var req struct {
		ID         int    `form:"ID,omitempty"`
		Username   string `form:"Username,omitempty"`
		Email      string `form:"Email,omitempty"`
		Phone      string `form:"Phone,omitempty"`
		Department *int   `form:"Department,omitempty"` // 使用指针类型
		Avatar     string `form:"Avatar,omitempty"`
		PageSize   int    `form:"pageSize" binding:"required"`
		PageNum    int    `form:"pageNum" binding:"required"`
	}

	// 绑定查询字符串参数
	if err := ctx.ShouldBindQuery(&req); err != nil {
		response.CommonResp(ctx, 1, "参数错误", nil)
		return
	}

	// 2. 构建查询条件
	var users []models.User
	var total int64
	offset := (req.PageNum - 1) * req.PageSize

	query := global.Db.Model(&models.User{})

	// 使用辅助函数构建查询条件
	query = utils.BuildUserQuery(query, req)

	// 3. 查询用户列表（分页）
	if err := query.Offset(offset).Limit(req.PageSize).Find(&users).Error; err != nil {
		response.CommonResp(ctx, 1, "查询失败", nil)
		return
	}

	// 4. 查询总记录数（不分页）
	var countQuery = global.Db.Model(&models.User{})
	countQuery = utils.BuildUserQuery(countQuery, req)

	// 5. 获取总记录数
	if err := countQuery.Count(&total).Error; err != nil {
		response.CommonResp(ctx, 1, "查询总记录数失败", nil)
		return
	}

	// 6. 组织返回的数据
	var respUsers []response.RespUser
	for _, user := range users {
		respUsers = append(respUsers, response.ToResponseUser(user))
	}

	res := struct {
		Users []response.RespUser `json:"users"`
		Total int64               `json:"total"`
	}{
		Users: respUsers,
		Total: total,
	}

	// 7. 返回响应
	response.CommonResp(ctx, 0, "查询成功", res)
}

func GetUserByToken(ctx *gin.Context) {
	userID, ok := ctx.Get("userID")
	if !ok {
		response.CommonResp(ctx, 1, "请重新登录", nil)
	}
	userID = userID.(int)
	var user models.User
	if err := global.Db.First(&user, userID).Error; err != nil {
		response.CommonResp(ctx, 1, "用户不存在", nil)
		return
	}
	respUser := response.ToResponseUser(user)
	response.CommonResp(ctx, 0, "获取用户成功", gin.H{"user": respUser})
}
